package com.springBoot.service.impl;

import com.springBoot.commonClass.Utils;
import com.springBoot.entity.DataEntity;
import com.springBoot.entity.FieldsEntity;
import com.springBoot.exception.BusinessFailureException;
import com.springBoot.repository.DataRepository;
import com.springBoot.repository.FieldsRepository;
import com.springBoot.service.DataOperationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

@Service
public class DataOperationServiceImpl implements DataOperationService {

    @Autowired
    private DataRepository dataRepository;
    @Autowired
    private FieldsRepository fieldsRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteData(DataEntity dataEntity) {
        try{
            this.dataRepository.delete(dataEntity);
        }catch (Exception e){
            throw new BusinessFailureException(true);
        }
    }

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public Future<List<Map<String, String>>> batchUpdate(List<Map<String, String>> dataList) {
        String objId = dataList.get(0).get("objId");
        List<DataEntity> dataEntityList = new ArrayList<>();
        FieldsEntity fieldsEntity = new FieldsEntity();
        fieldsEntity.setObjId(objId);
        List<FieldsEntity> fieldsEntityList = this.fieldsRepository.selectByParams(fieldsEntity);
        for(Map<String, String> data: dataList){
            DataEntity dataEntity = new DataEntity();
            for(FieldsEntity field:fieldsEntityList){
                Utils.setFieldValueByName(field.getMapperName(), dataEntity, data.get(field.getLabel()));
            }
            dataEntity.setLastModifiedBy(data.get("lastModifiedBy"));
            dataEntity.setDataId(data.get("dataId"));
            dataEntityList.add(dataEntity);
            data.put("lastModifiedDateTime", dataEntity.getLastModifiedDateTime().toString());
        }
        Integer res = this.dataRepository.batchUpdate(dataEntityList);
        if(res != dataEntityList.size()){
            throw new BusinessFailureException(false);
        }
        return new AsyncResult<>(dataList);
    }

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<DataEntity> dataEntityList) {
        this.dataRepository.batchDeleteWithDataId(dataEntityList);
    }

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public Future<List<Map<String, String>>> batchInsert(List<Map<String, String>> dataList) {
        String objId = dataList.get(0).get("objId");
        FieldsEntity fieldsEntity = new FieldsEntity();
        fieldsEntity.setObjId(objId);
        List<FieldsEntity> fieldsEntityList = this.fieldsRepository.selectByParams(fieldsEntity);
        for(Map<String, String> data: dataList){
            DataEntity dataEntity = new DataEntity();
            dataEntity.setDataId(Utils.getUuid());
            dataEntity.setObjId(objId);
            dataEntity.setOrgId(data.get("orgId"));
            dataEntity.setCreateBy(data.get("createBy"));
            dataEntity.setLastModifiedBy(data.get("lastModifiedBy"));
            dataEntity.setOwnerId(data.get("ownerId"));
            for(FieldsEntity fEntity: fieldsEntityList){
                Utils.setFieldValueByName(fEntity.getMapperName(), dataEntity, data.get(fEntity.getLabel()));
            }
            dataRepository.insert(dataEntity);
            data.put("dataId", dataEntity.getDataId());
            data.put("lastModifiedDateTime", dataEntity.getLastModifiedDateTime().toString());
            data.put("createDateTime", dataEntity.getCreateDateTime().toString());
        }
        return new AsyncResult<>(dataList);
    }

}
